{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# torchvision transform\n",
    "对PIL.Image进行变换  \n",
    "class torchvision.transforms.Compose(transforms)  \n",
    "将多个transform组合起来使用。  \n",
    "参数：\n",
    "- transforms： 由transform构成的列表.   \n",
    "\n",
    "例子：  \n",
    "```python\n",
    "transforms.Compose([\n",
    "     transforms.CenterCrop(10),\n",
    "     transforms.ToTensor(),\n",
    " ])\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## torchvision.transforms.Scale\n",
    "class torchvision.transforms.Scale(size, interpolation=2)  \n",
    "将输入的 PIL.Image 重新改变大小成给定的 size，size 是最小边的边长。举个例子，如果原图的 height>width ，那么改变大小后的图片大小`(size*height/width, size)`。\n",
    "**用例:**  \n",
    "```python\n",
    "from torchvision import transforms\n",
    "from PIL import Image\n",
    "crop = transforms.Scale(12)\n",
    "img = Image.open('test.jpg')\n",
    "\n",
    "print(type(img))\n",
    "print(img.size)\n",
    "\n",
    "croped_img=crop(img)\n",
    "print(type(croped_img))\n",
    "print(croped_img.size)\n",
    "```\n",
    "<class 'PIL.PngImagePlugin.PngImageFile'>  \n",
    "(10, 10)  \n",
    "<class 'PIL.Image.Image'>  \n",
    "(12, 12)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## torchvision.transforms.CenterCrop\n",
    "class torchvision.transforms.CenterCrop(size)  \n",
    "将给定的PIL.Image进行中心切割，得到给定的size，size可以是tuple，(target_height, target_width)。size也可以是一个Integer，在这种情况下，切出来的图片的形状是正方形。\n",
    "\n",
    "## torchvision.transforms.RandomCrop\n",
    "class torchvision.transforms.RandomCrop(size, padding=0)  \n",
    "切割中心点的位置随机选取。size可以是tuple也可以是Integer。\n",
    "\n",
    "## torchvision.transforms.RandomHorizontalFlip\n",
    "class torchvision.transforms.RandomHorizontalFlip  \n",
    "随机水平翻转给定的PIL.Image,概率为0.5。即：一半的概率翻转，一半的概率不翻转。  \n",
    "\n",
    "## torchvision.transforms.RandomSizedCrop\n",
    "class torchvision.transforms.RandomSizedCrop(size, interpolation=2)  \n",
    "先将给定的PIL.Image随机切，然后再resize成给定的size大小。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## torchvision.transforms.Pad\n",
    "class torchvision.transforms.Pad(padding, fill=0)  \n",
    "将给定的PIL.Image的所有边用给定的pad value填充。 padding：要填充多少像素 fill：用什么值填充 \n",
    "\n",
    "例子：\n",
    "```\n",
    "from torchvision import transforms\n",
    "from PIL import Image\n",
    "padding_img = transforms.Pad(padding=10, fill=0)\n",
    "img = Image.open('test.jpg')\n",
    "\n",
    "print(type(img))\n",
    "print(img.size)\n",
    "\n",
    "padded_img=padding(img)\n",
    "print(type(padded_img))\n",
    "print(padded_img.size)\n",
    "```\n",
    "<class 'PIL.PngImagePlugin.PngImageFile'>  \n",
    "(10, 10)  \n",
    "<class 'PIL.Image.Image'>  \n",
    "(30, 30) #由于上下左右都要填充10个像素，所以填充后的size是(30,30) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 对Tensor进行变换\n",
    "class torchvision.transforms.Normalize(mean, std)  \n",
    "给定均值：(R,G,B) 方差：（R，G，B），将会把Tensor正则化。即：Normalized_image=(image-mean)/std。  \n",
    "\n",
    "## torchvision.transforms.ToTensor\n",
    "class torchvision.transforms.ToTensor  \n",
    "把一个取值范围是[0,255]的PIL.Image或者shape为(H,W,C)的numpy.ndarray，转换成形状为[C,H,W]，取值范围是[0,1.0]的torch.FloadTensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10, 10, 3)\n",
      "tensor([[[214, 131, 237,  29, 229,  94,  13,  98, 213, 138],\n",
      "         [119, 233,  39, 139, 163, 253, 220, 121,  39,  26],\n",
      "         [  9, 152, 131, 220, 209, 221, 239,   9, 134, 130],\n",
      "         [177, 106, 192, 145,  63, 138,  18, 124, 104, 119],\n",
      "         [ 51, 166, 224,  47,  25,  65, 128,  99,  11, 247],\n",
      "         [137, 101,  17, 242,  13,  83, 118, 112,  19, 253],\n",
      "         [202,  93, 171,   5, 223,  96, 170,  14, 192, 135],\n",
      "         [ 41, 153, 216, 239,  81,  56, 227,  41, 157,  21],\n",
      "         [147,   4, 119, 152, 175, 224, 219, 106, 168, 158],\n",
      "         [214, 173, 172, 192, 182, 160, 211,  88,  41, 152]],\n",
      "\n",
      "        [[155, 138,  50, 179, 202,  54,   9,  21,  97, 174],\n",
      "         [152,  27, 246,  54,  95, 132,  30, 165,  80,  27],\n",
      "         [180,  84, 107,  60,  32, 131,  60, 108,  47,  42],\n",
      "         [160,  27,  28, 114,  55, 130, 221,  80,  39,  47],\n",
      "         [139,  61,  66, 181, 182, 121,  58,  50,  67, 211],\n",
      "         [ 79, 234, 195, 153, 179,  94, 197, 235,  61,   5],\n",
      "         [221, 187, 103,   8,  39, 227, 133, 227, 235,  25],\n",
      "         [ 61,  55, 193,  58, 254,  50,  45,  14, 135, 123],\n",
      "         [216, 177,  31, 185,  94, 178,  87, 198, 122, 169],\n",
      "         [195, 149, 235, 119,   6,  58,  65, 247, 108, 106]],\n",
      "\n",
      "        [[ 83, 112,  26, 247,  63, 222, 115, 141,  52, 249],\n",
      "         [ 83,  67, 155, 190,  62,  48, 229,  40, 126, 247],\n",
      "         [ 51, 216, 100, 102, 225, 237, 169, 176, 165, 112],\n",
      "         [ 23,  20, 159,  43, 116, 131, 238, 222, 176, 168],\n",
      "         [210, 106,  51,  30, 243,   8, 248, 209, 120, 105],\n",
      "         [183,  99,  82, 142, 199,  46,  15,  26, 241,  14],\n",
      "         [ 71,  19, 204, 149, 235,  59, 249, 158,  85, 126],\n",
      "         [  5,  68,  21, 159, 225,  24, 105,  78,  43, 253],\n",
      "         [156, 194, 233,   0,  24, 220, 230,  66, 219, 202],\n",
      "         [ 34,  60, 149, 192,  82, 192, 157, 148,   9,  69]]],\n",
      "       dtype=torch.int32)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import torchvision\n",
    "\n",
    "data = np.random.randint(0, 255, size=300)\n",
    "img = data.reshape(10,10,3)\n",
    "print(img.shape)\n",
    "img_tensor = torchvision.transforms.ToTensor()(img) # 转换成tensor\n",
    "print(img_tensor)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## torchvision.transforms.ToPILImage\n",
    "class torchvision.transforms.ToPILImage  \n",
    "将shape为(C,H,W)的Tensor或shape为(H,W,C)的numpy.ndarray转换成PIL.Image，值不变。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**通用变换**\n",
    "##  torchvision.transforms.Lambda\n",
    "class torchvision.transforms.Lambda(lambd)  \n",
    "使用lambd作为转换器。  \n",
    "具体详情见余霆嵩老师的教程，比较全面"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
